package com.sanpu.kxe.rxservice;

import android.text.TextUtils;
import android.util.Log;

import com.sanpu.kxe.business.login.bean.LoginOutput;
import com.sanpu.kxe.common.cache.CacheManage;
import com.sanpu.kxe.common.cache.CacheModel;
import com.sanpu.kxe.common.utils.Base64;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import static com.sanpu.kxe.utils.SignUtil.bytes2Hex;

/**
 * Description：请求报文加密、返回报文解密
 * Created by 薛勇军 on 2018/6/27.
 */

public class DataUtils {

    /**
     * 公钥
     */
    public static final String publicKey = "E555F1E8A5E7B1353DE33142EF9ABFFE";

    /**
     * 返回报文解密
     * 登录前接口用公钥解密，登录后接口用私钥解密
     */
    public static String dataDecode(String respData, boolean isPublicKey) {
        return decode(getKey(isPublicKey), respData);
    }

    /**
     * 请求报文加密
     * 登录前接口用公钥解密，登录后接口用私钥解密
     */
    public static String dataEncode(String key, String reqData) {
        return encode(key, reqData);
    }

    /**
     * 返回加解密钥
     * 登录前接口用公钥解密，登录后接口用私钥解密
     */
    public static String getKey(boolean isPublicKey) {
        if (isPublicKey) {
            return DataUtils.publicKey;
        } else {
            LoginOutput loginOutput = CacheManage.getInstance().getCache(CacheModel.LOGIN_KEY);
            if (loginOutput != null) {
                return loginOutput.getPrivateKey();
            }
            return "";
        }
    }

    /**
     * DES算法，加密
     *
     * @param data 待加密字符串
     * @param key  加密私钥，长度不能够小于8位
     * @return 加密后的字节数组，一般结合Base64编码使用
     */
    private static String encode(String key, String data) {
        if (data == null)
            return null;
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key.getBytes());
            // 创建一个密匙工厂，然后用它把DESKeySpec转换成
            // 一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey secretKey = keyFactory.generateSecret(dks);
            // using DES in ECB mode
            Cipher cipher = Cipher.getInstance("DES");
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
            // 执行加密操作
            byte[] bytes = cipher.doFinal(data.getBytes("utf-8"));
            return Base64.encode(bytes);
            // return byte2String(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return data;
        }
    }

    /**
     * DES算法，解密
     *
     * @param data 待解密字符串
     * @param key  解密私钥，长度不能够小于8位
     * @return 解密后的字节数组
     */
    private static String decode(String key, String data) {
        if (data == null)
            return null;
        try {
            // DES算法要求有一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
            // 从原始密匙数据创建一个DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key.getBytes());
            // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
            // 一个SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            // key的长度不能够小于8位字节
            SecretKey securekey = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
            return new String(cipher.doFinal(Base64.decode(data)));
        } catch (Exception e) {
            e.printStackTrace();
            return data;
        }
    }

    /**
     * 密码加密算法
     *
     * @param field
     * @param checkValue
     * @return
     */
    public static String encryptEncode(String key, String field, String checkValue) {
        try {
            if (TextUtils.isEmpty(field)) {
                return "";
            }
            StringBuffer sb = new StringBuffer();
            if (field.length() > 9) {
                sb.append(field.length());
            } else {
                sb.append("0" + field.length());
            }
            sb.append(field);
            sb.append(checkValue);
            String result = encode(key, sb.toString());
            return stringToAscii(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * String 转 ascii
     *
     * @param value
     */
    private static String stringToAscii(String value) {
        StringBuffer sbu = new StringBuffer();
        try {
            byte[] b = value.getBytes();
            for (int i = 0; i < b.length; i++) {
                sbu.append(Integer.toHexString(b[i] & 0xff));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e("data", sbu.toString());
        return sbu.toString();
    }

    /**
     * SHA加密
     *
     * @param strSrc
     *            明文
     * @return 加密之后的密文
     */
    public static String shaEncrypt(String strSrc) {
        MessageDigest md = null;
        String strDes = null;
        byte[] bt = strSrc.getBytes();
        try {
            md = MessageDigest.getInstance("SHA-256");// 将此换成SHA-1、SHA-512、SHA-384等参数
            md.update(bt);
            strDes = bytes2Hex(md.digest()); // to HexString
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
        return strDes;
    }

    /**
     * md5加密
     *
     * @param str 需要md5加密的信息
     * @return 加密后的md5字符串
     */
    public static String getMD5Str(String str) {
        if (TextUtils.isEmpty(str)) {
            return "";
        }
        StringBuffer buf;
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte b[] = md.digest();
            int i;
            buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString().toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}
